import SensorUtils from "../SensorUtils.js";
import component from "../../Component.js"
import VideoManager from "../videomanager/VideoManager.js"

import {
    BroadcastStatus,
    LayerType,
    ServiceType,
    StaffStatusText,
    TreeNodeParent,
} from "../../../experience/db/Type.js"

import { URL } from "../../../configure/Assets.js"

const Overlay = ol.Overlay;
const Icon = ol.style.Icon;

// 最外层目录的那几个节点的名称
const rootNodeList = [
    '安全监控',
    '人员定位',
    '应急广播',
    '视频监控',
    '通风系统'
]

export default class SensorPreview extends component {
    constructor() { super() }

    async control() {
        // 创建 摄像头的视频管理器组件实例
        this.videoManager = new VideoManager({hlsUrl: URL.HLS_URL});
        this.sensorUtil = new SensorUtils();
        // 触发设备定位时  gis元素浮动效果的图标 overlay
        const stationIcon_overlay_container = document.getElementById("sm_stationIcon_overlay")
        const broadcastIcon_overlay_container = document.getElementById("sm_broadcastIcon_overlay")
        const gasIcon_overlay_container = document.getElementById("sm_gasIcon_overlay")

        this.stationIcon_overlay = new Overlay({element: stationIcon_overlay_container, offset: [-17, -45], autoPan: true})
        this.broadcastIcon_overlay = new Overlay({element: broadcastIcon_overlay_container, offset: [-17, -45], autoPan: true})
        this.gasIcon_overlay = new Overlay({element: gasIcon_overlay_container, offset: [-17, -45], autoPan: true})

        this.drawer.map.addOverlay(this.stationIcon_overlay);
        this.drawer.map.addOverlay(this.broadcastIcon_overlay);
        this.drawer.map.addOverlay(this.gasIcon_overlay);

        // 在前端缓存 device info的列表
        this.device_infos = await this.sensorUtil.device_infos()
        // gis 上广播站触发点击
        this.emitter.on('smbroadcast-feature-click', async () => {
            // const node_id = this.emitter.params[0]
            // const normalX = null,normalY = null
            // this.stationIcon_overlay.setPosition([normalX, normalY]);

        })

        // gis上摄像头触发点击
        this.emitter.on('smvideo-feature-click', async () => {
            const node_id = this.emitter.params[0]
            const option = {channel, ip, manufacture, password, port, username}
            // videoInfoArr的格式为 [video, hls, id],分别代表 生成的video标签的dom对象，hls对象（管理流媒体的），每个hls的id
            const videoInfoArr = this.videoManager.makeVideo(option)

        })

        // gis上传感器或者监控分站触发点击
        this.emitter.on('smgas-feature-click', async () => {
            const node_id = this.emitter.params[0]
        })

        // 开启定时器 去定时更新 gis上的传感器
        this.refreshGasTimer = setInterval(() => {
            // 重新渲染 gas图层
            this.refreshLayer(LayerType.SMGas)
        }, 5000)
        // 初始化 对外暴露的接口emitter
        this.MessageEmitter()

    }

    template() {

        const sm_stationIcon_overlay = `<div id="sm_stationIcon_overlay" class="smIconOverlay">
                                            <i class="sm_stationIcon" style="cursor: pointer;">
                                                <img src="/assets/images/safe_monitor/station.svg">
</i>
                                        </div>`
        const sm_broadcastIcon_overlay = `<div id="sm_broadcastIcon_overlay" class="smIconOverlay">
                                            <i class="sm_broadcastIcon" style="cursor: pointer;">
                                            <img src="/assets/images/safe_monitor/broadcast.svg">
</i>
                                        </div>`
        const sm_gasIcon_overlay = `<div id="sm_gasIcon_overlay" class="smIconOverlay">
                                            <i class="sm_gasIcon" style="cursor: pointer;">
                                                <img src="">
</i>
                                        </div>`
        this.$$("#article").append(sm_stationIcon_overlay);
        this.$$("#article").append(sm_broadcastIcon_overlay);
        this.$$("#article").append(sm_gasIcon_overlay);
    }

    // 获取传感器，监控分站，广播分站，摄像头（这几类设备的总和）已经被设置过位置的设备列表
    async setted_device_list() {
        const settedBroads = await this.sensorUtil.setted_broadcast_list()
        const settedSensors = await this.sensorUtil.setted_sensor_list()
        const settedVideos = await this.sensorUtil.setted_video_list()
        return {
            settedBroads,
            settedSensors,
            settedVideos
        }
    }

    // 根据 图层类型，重新渲染 对应图层
    async refreshLayer(type) {
        switch (type) {
            case LayerType.SMStaff:
                await this.drawer._safeMonitorStaff()
                break
            case LayerType.SMBroadCast:
                await this.drawer._safeMonitorBroadcast()
                break
            case LayerType.SMVideo:
                await this.drawer._safeMonitorVideo()
                break
            case LayerType.SMGas:
                await this.drawer._safeMonitorGas()
                break
            case LayerType.SMVentilate:
                await this.drawer._safeMonitorVentilate()
                break
            default:
                break
        }

    }

// 根据 图层类型，隐藏 对应图层
    hiddenLayer(type) {
        switch (type) {
            case LayerType.SMStaff:
                this.drawer.source(LayerType.SMStaff).clear()
                break
            case LayerType.SMBroadCast:
                this.drawer.source(LayerType.SMBroadCast).clear()
                break
            case LayerType.SMVideo:
                this.drawer.source(LayerType.SMVideo).clear()
                break
            case LayerType.SMGas:
                this.drawer.source(LayerType.SMGas).clear()
                break
            case LayerType.SMVentilate:
                this.drawer.source(LayerType.SMVentilate).clear()
                break
            default:
                break
        }
    }
    // 树节点 单击地下广播节点触发函数
    async broadcastNodeClick(node_id) {
        console.log('触发了地下广播单击')
        const {data: position_broadcast} = await this.api.getSmPosition(ServiceType.Mine_Id, node_id, ServiceType.BroadCast)
        const {x, y} = position_broadcast
        const typeObj = {type: '广播站', node_id}
        this.sensorUtil.featureLocate([x, y], typeObj)
    }

    async gasStationNodeClick(treenode) {
        const {data: position} = await this.api.getSmPosition(ServiceType.Mine_Id, treenode.node_id, ServiceType.Gas)
        const coordinate = [position.x, position.y]
        let typeObj = {node_id: treenode.node_id}
        if (treenode.type === '传感器') {
            typeObj.type = '传感器'
        } else {
            typeObj.type = '监控分站'
        }
        this.sensorUtil.featureLocate(coordinate, typeObj)
        // 体现 监控分站与传感器之间的从属关系
        this.sensorUtil.highLightStationRelation(treenode)
    }

    // 单击 tree里面的摄像头
    async videoNodeClick(node_id) {
        const {data: position_video} = await this.api.getSmPosition(ServiceType.Mine_Id, node_id, ServiceType.Video)
        const {x, y} = position_video
        const typeObj = {type: '摄像头', node_id}
        this.sensorUtil.featureLocate([x, y], typeObj)
    }

    // 单击 tree里面的通风设备
    async ventilateNodeClick(node_id) {

        const {data: positionInfo} = await this.api.getSmPosition(ServiceType.Mine_Id, node_id, ServiceType.Gas)
        const {x, y} = positionInfo
        const typeObj = {type: 'ventilation', node_id}
        this.sensorUtil.featureLocate([x, y], typeObj)

    }

    // 单击 监控分站下的传感器
    async gasSensorNodeClick(treenode) {
        const {data: position} = await this.api.getSmPosition(ServiceType.Mine_Id, treenode.node_id, ServiceType.Gas)
        const coordinate = [position.x, position.y]
        this.sensorUtil.featureLocate(coordinate, {type: '传感器', node_id: treenode.node_id})
        this.sensorUtil.highLightSensorRelation(treenode)
    }

    // 这个函数 应该有两个功能，一个是定位，浮动gis元素，一个是通过postmessage把所要定位的元素的详细信息返回回去
    // 两个情况下 会触发这个函数。  1.外部前端 通过postmessage手动触发。 2.在gis点击元素的时候触发
    async NodeClick(event, treeId, treeNode) {
        if (rootNodeList.includes(treeNode.name)) {
            // do nothing
        } else {
            const {node_id, parent_id} = treeNode
            switch (parent_id) {
                case TreeNodeParent.BroadCast:
                    this.broadcastNodeClick(node_id)
                    break
                case TreeNodeParent.Gas:
                    // 触发点击的是监控分站
                    this.gasStationNodeClick(treeNode)
                    break
                case TreeNodeParent.Video:
                    // 点击的是摄像头
                    this.videoNodeClick(node_id)
                    break
                case TreeNodeParent.Ventilate:
                    // 点击 树上的通风设备
                    this.ventilateNodeClick(node_id)
                    break
                default:
                    // 除开上面的以外，触发点击的就只会是监控分站下的传感器了
                    this.gasSensorNodeClick(treeNode)
                    break
            }
        }
    }

    // 对外部嵌套 网页暴露的功能接口的emitter
    MessageEmitter() {
        // 预览  距离测量  emit事件
        this.emitter.on('outer-distance-measure', () => {
            this.$$('#measure').click()
        })

        // 预览  安全监控树数据获取  emit事件
        this.emitter.on('outer-gas-treedata-get', () => {
            const gasTreeData = []
            this.utils.postMessage({from: 'SafeMonitor', type: 'SM_GAS_TREEDATA_GET', data: gasTreeData})
        })

        // 预览  安全监控 所有已经设置过位置的传感器，分站信息列表  emit事件
        this.emitter.on('outer-gas-selecteddata-get', () => {
            const data = this.gasSelectedList
            this.utils.postMessage({from: 'SafeMonitor', type: 'SM_GAS_SELECTEDDATA_GET', data})
        })

        // 预览下， 根据treenode在gis上进行定位
        this.emitter.on('outer-treenode-locate', () => {
            const treenode = this.emitter.params[0]
            this.NodeClick(null,null,treenode)
        })

        // 预览下， 广播站渲染用图标渲染
        this.emitter.on('outer-broadcast-render-by-icon', () => {
            const features = this.drawer.source(LayerType.SMBroadCast).getFeatures()
            const Image = new Icon({ src:'/assets/images/safe_monitor/broadcastIcon.svg' })
            features.forEach((f) => {
                const style = f.getStyle()
                style.setImage(Image)
                f.setStyle(style)
            })

        })

        // 预览下， 广播站渲染用小点渲染
        this.emitter.on('outer-broadcast-render-by-point', () => {
            const features = this.drawer.source(LayerType.SMBroadCast).getFeatures()
            const Image = new Icon({ src:'/assets/images/safe_monitor/EllipseBlue.svg' })
            features.forEach((f) => {
                const style = f.getStyle()
                style.setImage(Image)
                f.setStyle(style)
            })

        })

        // 预览下， 传感器渲染用图标渲染
        this.emitter.on('outer-sensor-render-by-icon', () => {
            const features = this.drawer.source(LayerType.SMGas).getFeatures()
            const Image = new Icon({ src:'/assets/images/safe_monitor/gas/sensorIcons/fencheng.svg' })
            features.forEach((f) => {
                // console.log('sensor type',f.get('node_type'))
                const style = f.getStyle()
                style.setImage(Image)
                f.setStyle(style)
            })
        })

        // 预览下， 传感器渲染用小点点渲染
        this.emitter.on('outer-sensor-render-by-point', () => {
            const features = this.drawer.source(LayerType.SMGas).getFeatures()
            const Image = new Icon({ src:'/assets/images/safe_monitor/EllipseOrange.svg' })
            features.forEach((f) => {
                const style = f.getStyle()
                style.setImage(Image)
                f.setStyle(style)
            })
        })
        /*
        华丽的分割线
        ------------------------------------------------------------
        -------------------------------------------------------------------
        --------------------------------------------------------------------
        ---------------------------------------------------------------------
        */
        // 根据外部传过来的搜索关键字。对安全监控分站设备进行模糊查询
        this.emitter.on('device-search-sensor-station', async () => {
            const {keyWord:keyword,page_num,page_size} = this.emitter.params[0]
            const setted_device_list = await this.setted_device_list()
            const device_list = setted_device_list.settedSensors.data
            const {gas_infos:sensor_infos} = this.device_infos
            // 信息合并
            device_list.forEach((device) => {
                const target_info = sensor_infos.find((info) => {
                    return info.node_id == device.node_id
                })
                device.node_type = target_info.node_type
                device.place = target_info.place
                device.children = []
            })
            // 筛选出监控分站且满足关键字搜索条件的列表
            const station_device_list = device_list.filter((item) => {
                return item.node_type == '安全监控分站' && (item.node_id.includes(keyword) || item.place.includes(keyword))
            })
            // 生成 监控分站与传感器之间的树结构
            station_device_list.forEach((station) => {
                device_list.forEach((device) => {
                    if(device.parent_id == station.node_id) {
                        station.children.push(device)
                    }
                })
            })
            const pagenationInfos = this.sensorUtil.paginize(station_device_list,page_num,page_size)
            this.utils.postMessage({from: 'valkyrja', type: 'CATEGORY_KEYWORD_SEARCH', pagenationInfos})
        })

        // 根据外部传过来的搜索关键字。对传感器设备进行模糊查询
        this.emitter.on('device-search-sensor-node', async () => {
            const {keyWord:keyword,page_num,page_size} = this.emitter.params[0]
            const setted_device_list = await this.setted_device_list()
            const device_list = setted_device_list.settedSensors.data
            const {gas_infos:sensor_infos} = this.device_infos
            // 信息合并
            device_list.forEach((device) => {
                const target_info = sensor_infos.find((info) => {
                    return info.node_id == device.node_id
                })
                device.node_type = target_info.node_type
                device.place = target_info.place
                device.children = []
            })
            // 筛选出监控分站且满足关键字搜索条件的列表
            const sensor_device_list = device_list.filter((item) => {
                return item.node_type !== '安全监控分站' && (item.node_id.includes(keyword) || item.place.includes(keyword))
            })
            const pagenationInfos = this.sensorUtil.paginize(sensor_device_list,page_num,page_size)
            this.utils.postMessage({from: 'valkyrja', type: 'CATEGORY_KEYWORD_SEARCH', pagenationInfos})
        })

        // 根据外部传过来的搜索关键字。对广播站设备进行模糊查询
        this.emitter.on('device-search-broadcast-node', async () => {
            const {keyWord:keyword,page_num,page_size} = this.emitter.params[0]
            const setted_device_list = await this.setted_device_list()
            const device_list = setted_device_list.settedBroads.data
            const broadcast_device_list = device_list.filter((item) => {
                return  (item.node_id.includes(keyword) || item.place.includes(keyword))
            })
            const pagenationInfos = this.sensorUtil.paginize(broadcast_device_list,page_num,page_size)
            this.utils.postMessage({from: 'valkyrja', type: 'CATEGORY_KEYWORD_SEARCH', pagenationInfos})
        })

        // 根据外部传过来的搜索关键字。对摄像头设备进行模糊查询
        this.emitter.on('device-search-video-node', async () => {
            const {keyWord:keyword,page_num,page_size} = this.emitter.params[0]
            const setted_device_list = await this.setted_device_list()
            const device_list = setted_device_list.settedVideos.data
            const video_device_list = device_list.filter((item) => {
                return  (item.node_id.includes(keyword) || item.place.includes(keyword))
            })
            const pagenationInfos = this.sensorUtil.paginize(video_device_list,page_num,page_size)
            this.utils.postMessage({from: 'valkyrja', type: 'CATEGORY_KEYWORD_SEARCH', pagenationInfos})
        })

    }
}
